using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace MartinRL.ProjectEuler.Sequences
{
    /// <summary>
    /// Spec: http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibFormula.html#logs
    /// </summary>
    public class FibonacciTermDigitsSequence : IEnumerable<ushort>
    {
        private readonly double phi;

        public FibonacciTermDigitsSequence()
        {
            phi = (1d + 5d.Sqrt()) / 2d; // spec: http://en.wikipedia.org/wiki/Phi
        }

        public IEnumerator<ushort> GetEnumerator()
        {
            return ((ushort)0).ToMax()
                .Select(CalculateTermDigits)
                .GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        private ushort CalculateTermDigits(ushort index)
        {
            if (index == 0) return 1;
            if (index == 1) return 1;

            return (ushort)(index * phi.Log10() - 5d.Log10() / 2 + 1d);
        }
    }
}